﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using JilyGameFramework.Controls;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input.Touch;

namespace JilyGameFramework.Manager
{
    public class ScreenManager : DrawableGameComponent
    {
        private bool isInitialized = false;

        InputManager input;
        public InputManager Input
        {
            get
            {
                return input;
            }
            private set
            {
                input = value;
            }
        }

        public ContentManager Content { get; private set; }

        private List<GameScreen> screens;
        public List<GameScreen> Screens
        {
            get { return screens; }
            set { screens = value; }
        }

        private List<GameScreen> screensUpdate;
        public List<GameScreen> ScreensUpdate
        {
            get { return screensUpdate; }
            set { screensUpdate = value; }
        }

        private List<RenderTarget2D> transitions;
        public List<RenderTarget2D> Transitions
        {
            get { return transitions; }
            set { transitions = value; }
        }

        public SpriteBatch SpriteBatch { get; private set; }

        #region 屏幕大小换算

        /// <summary>
        /// 屏幕大小
        /// </summary>
        public Viewport ScreenDisplayMode
        {
            get
            {
                return this.GraphicsDevice.Viewport;
            }
        }

        /// <summary>
        /// 主界面工作大小
        /// </summary>
        public Rectangle ScreenViewPort
        {
            get
            {
                return this.GraphicsDevice.ScissorRectangle;
            }
        }

        double? spanWidth;
        public double SpanWidth
        {
            get
            {
                if (spanWidth == null)
                {
                    spanWidth = ScreenDisplayMode.Width / (double)ScreenViewPort.Width;
                }
                return spanWidth.Value;
            }
        }

        double? spanHeight;
        public double SpanHeight
        {
            get
            {
                if (spanHeight == null)
                {
                    spanHeight = ScreenDisplayMode.Height / (double)ScreenViewPort.Height;
                }
                return spanHeight.Value;
            }
        }

        #endregion

        public ScreenManager(Game game)
            : base(game)
        {
            screens = new List<GameScreen>();
            screensUpdate = new List<GameScreen>();
            transitions = new List<RenderTarget2D>();

            TouchPanel.EnabledGestures = GestureType.None;

            this.Content = game.Content;
            this.Content.RootDirectory = "Content";

            this.Input = new InputManager(this);
        }

        public override void Initialize()
        {
            base.Initialize();
            isInitialized = true;
        }

        protected override void LoadContent()
        {
            base.LoadContent();
            this.SpriteBatch = new SpriteBatch(GraphicsDevice);
            Screens.ForEach(i => i.LoadContent());
            input.LoadContent();
        }

        protected override void UnloadContent()
        {
            base.UnloadContent();
            Screens.ForEach(i => i.UnLoadContent());
        }

        public void AddScreen(GameScreen screen)
        {
            screen.ScreenManager = this;
            if (isInitialized)
            {
                screen.LoadContent();
            }

            Screens.Add(screen);
        }

        public void RemoveScreen(GameScreen screen)
        {
            if (isInitialized)
            {
                screen.UnLoadContent();
            }
            Screens.Remove(screen);
        }

        protected override void OnVisibleChanged(object sender, EventArgs args)
        {
            base.OnVisibleChanged(sender, args);
        }

        public override void Update(GameTime gameTime)
        {
            this.Input.Update(gameTime);
            base.Update(gameTime);

            screensUpdate.Clear();
            Screens.ForEach(i => screensUpdate.Add(i));
            screensUpdate.ForEach(i => i.Update(gameTime));
        }

        public override void Draw(GameTime gameTime)
        {
            base.Draw(gameTime);
            this.Input.Draw(gameTime);
            foreach (var screen in Screens)
            {
                screen.Draw(gameTime);
            }
        }

    }
}
